{{>partial_header}}
package {{packageName}}

{{#operations}}
import (
	{{#hasBodyParams}}
	"encoding/json"
	{{/hasBodyParams}}
	{{#hasOptionalBodyParams}}
	"errors"
	"io"
	{{/hasOptionalBodyParams}}
	"net/http"
	"strings"
{{#imports}}	"{{import}}"
	{{/imports}}
{{#hasPathParams}}

{{#routers}}
	{{#mux}}
	"github.com/gorilla/mux"
	{{/mux}}
	{{#chi}}
	"github.com/go-chi/chi/v5"
	{{/chi}}
{{/routers}}
{{/hasPathParams}}
)
{{/operations}}

// {{classname}}Controller binds http requests to an api service and writes the service results to the http response
type {{classname}}Controller struct {
	service {{classname}}Servicer
	errorHandler ErrorHandler
}

// {{classname}}Option for how the controller is set up.
type {{classname}}Option func(*{{classname}}Controller)

// With{{classname}}ErrorHandler inject ErrorHandler into controller
func With{{classname}}ErrorHandler(h ErrorHandler) {{classname}}Option {
	return func(c *{{classname}}Controller) {
		c.errorHandler = h
	}
}

// New{{classname}}Controller creates a default api controller
func New{{classname}}Controller(s {{classname}}Servicer, opts ...{{classname}}Option) *{{classname}}Controller {
	controller := &{{classname}}Controller{
		service:      s,
		errorHandler: DefaultErrorHandler,
	}

	for _, opt := range opts {
		opt(controller)
	}

	return controller
}

// Routes returns all the api routes for the {{classname}}Controller
func (c *{{classname}}Controller) Routes() Routes {
	return Routes{
{{#operations}}
	{{#operation}}
		"{{operationId}}": Route{
			"{{{operationId}}}",
			strings.ToUpper("{{httpMethod}}"),
			"{{{basePathWithoutHost}}}{{{path}}}",
			c.{{operationId}},
		},
	{{/operation}}
{{/operations}}
	}
}

// OrderedRoutes returns all the api routes in a deterministic order for the {{classname}}Controller
func (c *{{classname}}Controller) OrderedRoutes() []Route {
	return []Route{
{{#operations}}
	{{#operation}}
		Route{
			"{{{operationId}}}",
			strings.ToUpper("{{httpMethod}}"),
			"{{{basePathWithoutHost}}}{{{path}}}",
			c.{{operationId}},
		},
	{{/operation}}
{{/operations}}
	}
}

{{#operations}}{{#operation}}

// {{nickname}} - {{{summary}}}
{{#isDeprecated}}
// Deprecated
{{/isDeprecated}}
func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Request) {
	{{#hasFormParams}}
	{{#isMultipart}}
	if err := r.ParseMultipartForm(32 << 20); err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{/isMultipart}}
	{{^isMultipart}}
	if err := r.ParseForm(); err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{/isMultipart}}
	{{/hasFormParams}}
	{{#routers}}
		{{#mux}}
			{{#hasPathParams}}
	params := mux.Vars(r)
			{{/hasPathParams}}
		{{/mux}}
	{{/routers}}
	{{#hasQueryParams}}
	query, err := parseQuery(r.URL.RawQuery)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{/hasQueryParams}}
	{{#allParams}}
	{{#isPathParam}}
	{{#isNumber}}
	{{paramName}}Param, err := parseNumericParameter[float32](
		{{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}},{{#defaultValue}}
		WithDefaultOrParse[float32]({{defaultValue}}, parseFloat32),{{/defaultValue}}{{^defaultValue}}{{#required}}
		WithRequire[float32](parseFloat32),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}}
		WithParse[float32](parseFloat32),{{/required}}{{/defaultValue}}{{#minimum}}
		WithMinimum[float32]({{minimum}}),{{/minimum}}{{#maximum}}
		WithMaximum[float32]({{maximum}}),{{/maximum}}
	)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/isNumber}}
	{{#isFloat}}
	{{paramName}}Param, err := parseNumericParameter[float32](
		{{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}},{{#defaultValue}}
		WithDefaultOrParse[float32]({{defaultValue}}, parseFloat32),{{/defaultValue}}{{^defaultValue}}{{#required}}
		WithRequire[float32](parseFloat32),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}}
		WithParse[float32](parseFloat32),{{/required}}{{/defaultValue}}{{#minimum}}
		WithMinimum[float32]({{minimum}}),{{/minimum}}{{#maximum}}
		WithMaximum[float32]({{maximum}}),{{/maximum}}
	)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/isFloat}}
	{{#isDouble}}
	{{paramName}}Param, err := parseNumericParameter[float64](
		{{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}},{{#defaultValue}}
		WithDefaultOrParse[float64]({{defaultValue}}, parseFloat64),{{/defaultValue}}{{^defaultValue}}{{#required}}
		WithRequire[float64](parseFloat64),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}}
		WithParse[float64](parseFloat64),{{/required}}{{/defaultValue}}{{#minimum}}
		WithMinimum[float64]({{minimum}}),{{/minimum}}{{#maximum}}
		WithMaximum[float64]({{maximum}}),{{/maximum}}
	)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/isDouble}}
	{{#isLong}}
	{{paramName}}Param, err := parseNumericParameter[int64](
		{{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}},{{#defaultValue}}
		WithDefaultOrParse[int64]({{defaultValue}}, parseInt64),{{/defaultValue}}{{^defaultValue}}{{#required}}
		WithRequire[int64](parseInt64),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}}
		WithParse[int64](parseInt64),{{/required}}{{/defaultValue}}{{#minimum}}
		WithMinimum[int64]({{minimum}}),{{/minimum}}{{#maximum}}
		WithMaximum[int64]({{maximum}}),{{/maximum}}
	)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/isLong}}
	{{#isInteger}}
	{{paramName}}Param, err := parseNumericParameter[int32](
		{{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}},{{#defaultValue}}
		WithDefaultOrParse[int32]({{defaultValue}}, parseInt32),{{/defaultValue}}{{^defaultValue}}{{#required}}
		WithRequire[int32](parseInt32),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}}
		WithParse[int32](parseInt32),{{/required}}{{/defaultValue}}{{#minimum}}
		WithMinimum[int32]({{minimum}}),{{/minimum}}{{#maximum}}
		WithMaximum[int32]({{maximum}}),{{/maximum}}
	)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/isInteger}}
	{{#isDateTime}}
	{{paramName}}Param, err := parseTime({{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}})
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/isDateTime}}
	{{^isNumber}}
	{{^isFloat}}
	{{^isDouble}}
	{{^isLong}}
	{{^isInteger}}
	{{^isDateTime}}
	{{^isEnumRef}}
	{{paramName}}Param := {{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}}
	if {{paramName}}Param == "" {
		c.errorHandler(w, r, &RequiredError{"{{baseName}}"}, nil)
		return
	}
	{{/isEnumRef}}
	{{#isEnumRef}}
	{{paramName}}Param, err := New{{dataType}}FromValue({{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}})
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/isEnumRef}}
	{{/isDateTime}}
	{{/isInteger}}
	{{/isLong}}
	{{/isDouble}}
	{{/isFloat}}
	{{/isNumber}}
	{{/isPathParam}}
	{{#isQueryParam}}
	{{#isDateTime}}
	var {{paramName}}Param {{#isNullable}}*{{/isNullable}}time.Time
	if query.Has("{{baseName}}"){
		param, err := parseTime(query.Get("{{baseName}}"))
		if err != nil {
			c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
			return
		}

		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
	} else {
		{{#required}}
		c.errorHandler(w, r, &RequiredError{"{{baseName}}"}, nil)
		return
		{{/required}}
	}
	{{/isDateTime}}
	{{#isNumber}}
	var {{paramName}}Param {{#isNullable}}*{{/isNullable}}float32
	if query.Has("{{baseName}}") {
		param, err := parseNumericParameter[float32](
			query.Get("{{baseName}}"),
			WithParse[float32](parseFloat32),{{#minimum}}
			WithMinimum[float32]({{minimum}}),{{/minimum}}{{#maximum}}
			WithMaximum[float32]({{maximum}}),{{/maximum}}
		)
		if err != nil {
			c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
			return
		}

		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
	} else {
		{{#required}}
		c.errorHandler(w, r, &RequiredError{Field: "{{baseName}}"}, nil)
		return
		{{/required}}
		{{^required}}
		{{#defaultValue}}
		var param float32 = {{defaultValue}}
		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
		{{/defaultValue}}
		{{/required}}
	}
	{{/isNumber}}
	{{#isFloat}}
	var {{paramName}}Param {{#isNullable}}*{{/isNullable}}float32
	if query.Has("{{baseName}}") {
		param, err := parseNumericParameter[float32](
			query.Get("{{baseName}}"),
			WithParse[float32](parseFloat32),{{#minimum}}
			WithMinimum[float32]({{minimum}}),{{/minimum}}{{#maximum}}
			WithMaximum[float32]({{maximum}}),{{/maximum}}
		)
		if err != nil {
			c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
			return
		}

		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
	} else {
		{{#required}}
		c.errorHandler(w, r, &RequiredError{Field: "{{baseName}}"}, nil)
		return
		{{/required}}
		{{^required}}
		{{#defaultValue}}
		var param float32 = {{defaultValue}}
		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
		{{/defaultValue}}
		{{/required}}
	}
	{{/isFloat}}
	{{#isDouble}}
	var {{paramName}}Param {{#isNullable}}*{{/isNullable}}float64
	if query.Has("{{baseName}}") {
		param, err := parseNumericParameter[float64](
			query.Get("{{baseName}}"),
			WithParse[float64](parseFloat64),{{#minimum}}
			WithMinimum[float64]({{minimum}}),{{/minimum}}{{#maximum}}
			WithMaximum[float64]({{maximum}}),{{/maximum}}
		)
		if err != nil {
			c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
			return
		}

		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
	} else {
		{{#required}}
		c.errorHandler(w, r, &RequiredError{Field: "{{baseName}}"}, nil)
		return
		{{/required}}
		{{^required}}
		{{#defaultValue}}
		var param float64 = {{defaultValue}}
		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
		{{/defaultValue}}
		{{/required}}
	}
	{{/isDouble}}
	{{#isLong}}
	var {{paramName}}Param {{#isNullable}}*{{/isNullable}}int64
	if query.Has("{{baseName}}") {
		param, err := parseNumericParameter[int64](
			query.Get("{{baseName}}"),
			WithParse[int64](parseInt64),{{#minimum}}
			WithMinimum[int64]({{minimum}}),{{/minimum}}{{#maximum}}
			WithMaximum[int64]({{maximum}}),{{/maximum}}
		)
		if err != nil {
			c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
			return
		}

		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
	} else {
		{{#required}}
		c.errorHandler(w, r, &RequiredError{Field: "{{baseName}}"}, nil)
		return
		{{/required}}
		{{^required}}
		{{#defaultValue}}
		var param int64 = {{defaultValue}}
		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
		{{/defaultValue}}
		{{/required}}
	}
	{{/isLong}}
	{{#isInteger}}
	var {{paramName}}Param {{#isNullable}}*{{/isNullable}}int32
	if query.Has("{{baseName}}") {
		param, err := parseNumericParameter[int32](
			query.Get("{{baseName}}"),
			WithParse[int32](parseInt32),{{#minimum}}
			WithMinimum[int32]({{minimum}}),{{/minimum}}{{#maximum}}
			WithMaximum[int32]({{maximum}}),{{/maximum}}
		)
		if err != nil {
			c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
			return
		}

		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
	} else {
		{{#required}}
		c.errorHandler(w, r, &RequiredError{Field: "{{baseName}}"}, nil)
		return
		{{/required}}
		{{^required}}
		{{#defaultValue}}
		var param int32 = {{defaultValue}}
		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
		{{/defaultValue}}
		{{/required}}
	}
	{{/isInteger}}
	{{#isBoolean}}
	var {{paramName}}Param {{#isNullable}}*{{/isNullable}}bool
	if query.Has("{{baseName}}") {
		param, err := parseBoolParameter(
			query.Get("{{baseName}}"),
			WithParse[bool](parseBool),{{#minimum}}
			WithMinimum[bool]({{minimum}}),{{/minimum}}{{#maximum}}
			WithMaximum[bool]({{maximum}}),{{/maximum}}
		)
		if err != nil {
			c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
			return
		}

		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
	} else {
		{{#required}}
		c.errorHandler(w, r, &RequiredError{Field: "{{baseName}}"}, nil)
		return
		{{/required}}
		{{^required}}
		{{#defaultValue}}
		var param bool = {{defaultValue}}
		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
		{{/defaultValue}}
		{{/required}}
	}
	{{/isBoolean}}
	{{#isArray}}
	{{#items.isNumber}}
	{{paramName}}Param, err := parseNumericArrayParameter[float32](
		query.Get("{{baseName}}"), ",", {{required}},
		WithParse[float32](parseFloat32),{{#minimum}}
		WithMinimum[float32]({{minimum}}),{{/minimum}}{{#maximum}}
		WithMaximum[float32]({{maximum}}),{{/maximum}}
	)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/items.isNumber}}
	{{#items.isFloat}}
	{{paramName}}Param, err := parseNumericArrayParameter[float32](
		query.Get("{{baseName}}"), ",", {{required}},
		WithParse[float32](parseFloat32),{{#minimum}}
		WithMinimum[float32]({{minimum}}),{{/minimum}}{{#maximum}}
		WithMaximum[float32]({{maximum}}),{{/maximum}}
	)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
	return
	}
	{{/items.isFloat}}
	{{#items.isDouble}}
	{{paramName}}Param, err := parseNumericArrayParameter[float64](
		query.Get("{{baseName}}"), ",", {{required}},
		WithParse[float64](parseFloat64),{{#minimum}}
		WithMinimum[float64]({{minimum}}),{{/minimum}}{{#maximum}}
		WithMaximum[float64]({{maximum}}),{{/maximum}}
	)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/items.isDouble}}
	{{#items.isLong}}
	{{paramName}}Param, err := parseNumericArrayParameter[int64](
		query.Get("{{baseName}}"), ",", {{required}},
		WithParse[int64](parseInt64),{{#minimum}}
		WithMinimum[int64]({{minimum}}),{{/minimum}}{{#maximum}}
		WithMaximum[int64]({{maximum}}),{{/maximum}}
	)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/items.isLong}}
	{{#items.isInteger}}
	{{paramName}}Param, err := parseNumericArrayParameter[int32](
		query.Get("{{baseName}}"), ",", {{required}},
		WithParse[int32](parseInt32),{{#minimum}}
		WithMinimum[int32]({{minimum}}),{{/minimum}}{{#maximum}}
		WithMaximum[int32]({{maximum}}),{{/maximum}}
	)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/items.isInteger}}
	{{#items.isDateTime}}
	{{paramName}}Param, err := parseTimes(query.Get("{{baseName"}}))
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/items.isDateTime}}
	{{^items.isNumber}}
	{{^items.isFloat}}
	{{^items.isDouble}}
	{{^items.isLong}}
	{{^items.isInteger}}
	{{^items.isEnumRef}}
	var {{paramName}}Param []string
	if query.Has("{{baseName}}") {
		{{paramName}}Param = strings.Split(query.Get("{{baseName}}"), ",")
	}
	{{/items.isEnumRef}}
	{{#items.isEnumRef}}
	var {{paramName}}Param []{{items.dataType}}
	if query.Has("{{baseName}}") {
		paramSplits := strings.Split(query.Get("{{baseName}}"), ",")
		{{paramName}}Param = make([]{{items.dataType}}, 0, len(paramSplits))
		for _, param := range paramSplits {
			paramEnum, err := New{{items.dataType}}FromValue(param)
			if err != nil {
				c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
				return
			}
			{{paramName}}Param = append({{paramName}}Param, paramEnum)
		}
	}
	{{/items.isEnumRef}}
	{{/items.isInteger}}
	{{/items.isLong}}
	{{/items.isDouble}}
	{{/items.isFloat}}
	{{/items.isNumber}}
	{{/isArray}}
	{{^isNumber}}
	{{^isFloat}}
	{{^isDouble}}
	{{^isLong}}
	{{^isInteger}}
	{{^isBoolean}}
	{{^isArray}}
	{{^isDateTime}}
	var {{paramName}}Param {{#isNullable}}*{{/isNullable}}{{dataType}}
	if query.Has("{{baseName}}") {
		param := {{^isString}}{{dataType}}({{/isString}}query.Get("{{baseName}}"){{^isString}}){{/isString}}

		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
	} else {
		{{#required}}
		c.errorHandler(w, r, &RequiredError{Field: "{{baseName}}"}, nil)
		return
		{{/required}}
		{{^required}}
		{{#defaultValue}}
		param := {{^isString}}{{dataType}}({{/isString}}"{{defaultValue}}"{{^isString}}){{/isString}}
		{{paramName}}Param = {{#isNullable}}&{{/isNullable}}param
		{{/defaultValue}}
		{{/required}}
	}
	{{/isDateTime}}
	{{/isArray}}
	{{/isBoolean}}
	{{/isInteger}}
	{{/isLong}}
	{{/isDouble}}
	{{/isFloat}}
	{{/isNumber}}
	{{/isQueryParam}}
	{{#isFormParam}}
	{{#isFile}}
	var {{paramName}}Param {{#isArray}}[]*os.File{{/isArray}}{{^isArray}}*os.File{{/isArray}}
	{
	{{#isArray}}
		param, err := ReadFormFilesToTempFiles(r, "{{baseName}}")
		{{/isArray}}
		{{^isArray}}
		param, err := ReadFormFileToTempFile(r, "{{baseName}}")
		{{/isArray}}
		if err != nil {
			c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
			return
		}

		{{paramName}}Param = param
	}
	{{/isFile}}
	{{#isLong}}{{#isArray}}
	{{paramName}}Param, err := parseNumericArrayParameter[int64](
		r.FormValue("{{baseName}}"), ",", {{required}},
		WithParse[int64](parseInt64),{{#minimum}}
		WithMinimum[int64]({{minimum}}),{{/minimum}}{{#maximum}}
		WithMaximum[int64]({{maximum}}),{{/maximum}}
	)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/isArray}}{{/isLong}}
	{{#isInteger}}{{#isArray}}
	{{paramName}}Param, err := parseNumericArrayParameter[int32](
		r.FormValue("{{baseName}}"), ",", {{required}},
		WithParse[int32](parseInt32),{{#minimum}}
		WithMinimum[int32]({{minimum}}),{{/minimum}}{{#maximum}}
		WithMaximum[int32]({{maximum}}),{{/maximum}}
	)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Param: "{{baseName}}", Err: err}, nil)
		return
	}
	{{/isArray}}{{/isInteger}}
	{{^isFile}}
	{{^isLong}}
	{{#isArray}}
	{{paramName}}Param := strings.Split(r.FormValue("{{baseName}}"), ",")
	{{/isArray}}
	{{^isArray}}
	{{paramName}}Param := r.FormValue("{{baseName}}")
	{{/isArray}}
	{{/isLong}}
	{{/isFile}}
	{{/isFormParam}}
	{{#isHeaderParam}}
	{{paramName}}Param := r.Header.Get("{{baseName}}")
	{{/isHeaderParam}}
	{{#isBodyParam}}
	var {{paramName}}Param {{dataType}}
	d := json.NewDecoder(r.Body)
	{{^isAdditionalPropertiesTrue}}
	d.DisallowUnknownFields()
	{{/isAdditionalPropertiesTrue}}
	if err := d.Decode(&{{paramName}}Param); err != nil {{^required}}&& !errors.Is(err, io.EOF) {{/required}}{
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{#isArray}}
		{{#items.isModel}}
	for _, el := range {{paramName}}Param {
		if err := Assert{{baseType}}Required(el); err != nil {
			c.errorHandler(w, r, err, nil)
			return
		}
	}
		{{/items.isModel}}
	{{/isArray}}
	{{^isArray}}
		{{#isModel}}
	if err := Assert{{baseType}}Required({{paramName}}Param); err != nil {
		c.errorHandler(w, r, err, nil)
		return
	}
	if err := Assert{{baseType}}Constraints({{paramName}}Param); err != nil {
		c.errorHandler(w, r, err, nil)
		return
	}
		{{/isModel}}
	{{/isArray}}
	{{/isBodyParam}}
	{{/allParams}}
	result, err := c.service.{{nickname}}(r.Context(){{#allParams}}, {{#isNullable}}{{#isBodyParam}}&{{/isBodyParam}}{{/isNullable}}{{paramName}}Param{{/allParams}})
	// If an error occurred, encode the error with the status code
	if err != nil {
		c.errorHandler(w, r, err, &result)
		return
	}
	// If no error, encode the body and the result code
	_ = EncodeJSONResponse(result.Body, &result.Code,{{#addResponseHeaders}} result.Headers,{{/addResponseHeaders}} w)
}{{/operation}}{{/operations}}
